package com.sinothk.server.plus.office.stamper;

import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.StampingProperties;
import com.itextpdf.layout.element.Image;
import com.itextpdf.signatures.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;

public class StamperUtil {

    /**
     * 电子签章
     * @param src 需要签章的pdf文件路径
     * @param dest 签完章的pdf文件路径
     */
    public static void sign(String src, String dest)  {
        // keytool -genkeypair -alias stamper -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore d:/ittest/stamper.keystore -storepass 123456
        final String KEYSTORE = "D:\\ittest\\stamper.keystore";//keystore文件路径
        final char[] PASSWORD = "123456".toCharArray();// keystore密码
        final String STAMPER_SRC = "D:\\ittest\\123.png";//印章图片路径

        try (PdfReader reader = new PdfReader(src); FileOutputStream os = new FileOutputStream(dest);){
            //读取keystore ，获得私钥和证书链 jks
            KeyStore ks = KeyStore.getInstance("JKS");
            ks.load(new FileInputStream(KEYSTORE), PASSWORD);
            String alias = ks.aliases().nextElement();
            PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);
            Certificate[] chain = ks.getCertificateChain(alias);

            //创建签章工具PdfSigner、设定数字签章的属性
            PdfSigner stamper = new PdfSigner(reader, os, new StampingProperties());
            PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
            appearance.setReason("签名原因：系统自动签名盖章");
            appearance.setLocation("签名地点：xxx系统");
            appearance.setContact("联系方式：huanzi.qch@qq.com");

            //加盖图章图片
            ImageData img = ImageDataFactory.create(STAMPER_SRC);
            Image image = new Image(img);
            appearance.setPageNumber(1);
            appearance.setPageRect(new Rectangle(350, 150, 136, 136));  //image.getImageWidth() , image.getImageHeight()
            appearance.setSignatureGraphic(img);
            appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);

            //No such provider: BC : 问题解决，加BC库支持
            Security.addProvider(new BouncyCastleProvider());

            //摘要算法
            IExternalDigest digest = new BouncyCastleDigest();
            //签名算法
            IExternalSignature signature = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, BouncyCastleProvider.PROVIDER_NAME);

            //调用itext签名方法完成pdf签章
            stamper.setCertificationLevel(1);
            stamper.signDetached(digest,signature, chain, null, null, null, 0, PdfSigner.CryptoStandard.CMS);

            System.out.println("操作完成！");
        }catch (Exception e){
            e.printStackTrace();
            System.err.println("操作异常...");
        }
    }

    //测试
    public static void main(String[] args) {// http://seal.ssjjss.com/ 签章生成
        sign("D:\\ittest\\html2pdf1.pdf","D:\\ittest\\html2pdf_sign.pdf");
    }
}
